package com.lhb.boyixue.base;




import io.jsonwebtoken.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @author 86131
 * @version 1.0
 * @description 令牌工具
 * @date 2025/4/24 下午4:18
 */
@Slf4j
@Component
public class JwtUtil {
    private final JwtConfig jwtConfig;

    @Autowired
    public JwtUtil(JwtConfig jwtConfig) {
        this.jwtConfig = jwtConfig;
    }
    /**
     * 生成JWT Token
     * @param userId 用户ID
     * @param claims 自定义claims
     * @return JWT Token
     */
    public  String generateToken(String userId, Map<String, Object> claims) {
        if (claims == null) {
            claims = new HashMap<>();
        }

        // 设置JWT签发时间
        Date now = new Date();

        return Jwts.builder()
                .setClaims(claims)                      // 自定义claims
                .setSubject(userId)                    // 主题/用户openID
                .setIssuer(jwtConfig.getIssuer())                     // 签发者
                .setIssuedAt(now)                      // 签发时间
                .setExpiration(new Date(now.getTime() + jwtConfig.getExpire())) // 过期时间
                .signWith(jwtConfig.getSecretKey(), SignatureAlgorithm.HS256) // 签名算法
                .compact();
    }
    /**
     * 生成JWT Token (使用默认claims)
     * @param userId 用户ID
     * @return JWT Token
     */
    public  String generateToken(String userId) {
        return generateToken(userId, null);
    }

    /**
     * 从Token中获取Claims
     * @param token JWT Token
     * @return Claims
     */
    public  Claims parseToken(String token) {
        if (!StringUtils.hasText(token)) {
            return null;
        }

        try {
            return Jwts.parserBuilder()
                    .setSigningKey(jwtConfig.getSecretKey())
                    .build()
                    .parseClaimsJws(token)
                    .getBody();
        } catch (Exception e) {
            log.error("JWT解析失败: {}", e.getMessage());
            return null;
        }
    }
    /**
     * 验证JWT Token是否有效
     * @param token JWT Token
     * @return 是否有效
     */
    public  boolean verify(String token) {
        if (!StringUtils.hasText(token)) {
            return false;
        }

        try {
            Jwts.parserBuilder()
                    .setSigningKey(jwtConfig.getSecretKey())
                    .build()
                    .parseClaimsJws(token);
            return true;
        } catch (ExpiredJwtException e) {
            log.error("JWT Token已过期: {}", e.getMessage());
        } catch (UnsupportedJwtException e) {
            log.error("不支持的JWT Token: {}", e.getMessage());
        } catch (MalformedJwtException e) {
            log.error("JWT Token格式错误: {}", e.getMessage());
        } catch (SignatureException e) {
            log.error("JWT签名验证失败: {}", e.getMessage());
        } catch (IllegalArgumentException e) {
            log.error("JWT参数错误: {}", e.getMessage());
        } catch (Exception e) {
            log.error("JWT验证异常: {}", e.getMessage());
        }
        return false;
    }
    /**
     * 检查Token是否过期
     * @param token JWT Token
     * @return 是否过期
     */
    public  boolean isTokenExpired(String token) {
        Claims claims = parseToken(token);
        if (claims == null) {
            return false;
        }

        Date expiration = claims.getExpiration();
        long remainingTime = expiration.getTime() - System.currentTimeMillis();
        return remainingTime <=0;
    }
    /**
     * 刷新Token
     * @param token 原Token
     * @return 新Token
     */
    public  String refreshToken(String token) {
        Claims claims = parseToken(token);
        if (claims == null) {
            return null;
        }

        // 保留原claims
        Map<String, Object> newClaims = new HashMap<>(claims);

        // 移除标准claims
        newClaims.remove("iss");
        newClaims.remove("sub");
        newClaims.remove("aud");
        newClaims.remove("exp");
        newClaims.remove("nbf");
        newClaims.remove("iat");
        newClaims.remove("jti");

        return generateToken(claims.getSubject(), newClaims);
    }

    /**
     * 从Token中获取用户ID
     * @param token JWT Token
     * @return 用户ID
     */
    public  String getUserId(String token) {
        Claims claims = parseToken(token);
        return claims != null ? claims.getSubject() : null;
    }
    /**
     * 从Token中获取指定Claim
     * @param token JWT Token
     * @param claimName Claim名称
     * @return Claim值
     */
    public  Object getClaim(String token, String claimName) {
        Claims claims = parseToken(token);
        return claims != null ? claims.get(claimName) : null;
    }


}

